﻿#load "Symbols.fs"
#load "CSModel.fs"
#load "CSValidation.fs"
#load "CSSolver.fs"
open Symbols
open CSModel
open CSSolver

//assign digits to letters such that
// send + more = money
//http://www.mozart-oz.org/documentation/fdt/node15.html

//Note: This takes a while as the main constraint references all the variables
//this solver uses static variable ordering to search for solutions 
//for single bucket. Other strategies such as "fail-first" will give better results


let domain = intSet [for i in 0..9 -> i]
let firstDigitDomain = intSet [for i in 1..9 -> i]

let S = VarDef("S",firstDigitDomain)
let E = VarDef("E",domain)
let N = VarDef("N",domain)
let D = VarDef("D",domain)
let M = VarDef("M",firstDigitDomain)
let O = VarDef("O",domain)
let R = VarDef("R",domain)
let Y = VarDef("Y",domain)

let constraints =
    [
        //all different
        &S != &E; &S != &N; &S != &D; &S != &M; &S != &O; &S != &R; &S != &Y
        &E != &N; &E != &D; &E != &M; &E != &O; &E != &R; &E != &Y
        &N != &D; &N != &M; &N != &O; &N != &R; &N != &Y
        &D != &M; &D != &O; &D != &R; &D != &Y
        &M != &O; &M != &R; &M != &Y;
        &O != &R; &O != &Y
        &R != &Y
        //send + more = money
        ((&S * 1000I + &E * 100I + &N * 10I + &D) 
         + (&M * 1000I + &O * 100I + &R * 10I + &E))
         == (&M * 10000I + &O * 1000I + &N * 100I + &E * 10I + &Y)
    ]


let cs = ConstraintSystem([S;E;N;D;M;O;R;Y], constraints)

let solSet = solve cs

let ss =
    solSet 
    |> enumerateSolutions 
    |> Seq.toList 

